/*
 * listenhandler.h
 *
 *  Created on: 2013. 7. 19.
 *      Author: jjaehuny
 */

#ifndef LISTENHANDLER_H_
#define LISTENHANDLER_H_

#include <Dispatcher/Static.h>
#include "ChannelServer.h"

namespace CacheServer
{

class ListenHandler : public Dispatcher::ListenHandler<ChannelServer, Network::Packet>
{
public:
	ListenHandler() {}
	virtual ~ListenHandler() {}

	virtual void OnConnect(ChannelServer* pSession, const char* ip)
	{
		LOG(DEV, "(session_key:", pSession->GetSessionKey(), ", sock:", pSession->GetSocket(), ", ip:", ip, ")");
	}
	virtual void OnClose(ChannelServer* pSession, int nReason)
	{
		LOG(DEV, "(session_key:", pSession->GetSessionKey(), ", sock:", pSession->GetSocket(), ", errno:", nReason, " errstr:", strerror(errno), ")");

		typename Session::State* pState = pSession->GetState();
		if (NULL == pState)
		{
			LOG(ERR, "session has no state(session_key:", pSession->sessionKey_, ")");
			return ;
		}

		typename Session::State::Command pCommand = pState->GetCommand(1);
		if (NULL == pCommand)
		{
			LOG(ERR, "state has no command(session_key:", pSession->sessionKey_, ", command_id:", 1, ")");
			return ;
		}

		int start = GetTime();
		(*pCommand)(pSession, NULL);
		int end = GetTime();
		LOG(INF, "[ PROCESS COMMAND : ", 1 , " START : ", start, " END : ", end, " GAB : ", end - start, " ]");
	}
	virtual void OnRecvMsg(Session* pSession, Packet* pPacket)
	{
		typename Session::State* pState = pSession->GetState();
		if (NULL == pState)
		{
			LOG(ERR, "session has no state(session_key:", pSession->sessionKey_, ")");
			return ;
		}

		typename Session::State::Command pCommand = pState->GetCommand(pPacket->GetCommand());
		if (NULL == pCommand)
		{
			LOG(ERR, "state has no command(session_key:", pSession->sessionKey_, ", command_id:", pPacket->GetCommand(), ")");
			return ;
		}
		unsigned long start = GetTime();
		(*pCommand)(pSession, pPacket);
		unsigned long end = GetTime();
		LOG(INF, "[ PROCESS COMMAND : ", pPacket->GetCommand(), " START : ", start, " END : ", end, " GAB : ", end - start, " ]");
	}
	// return milli second
	unsigned int GetTime()
	{
		struct timespec ts;
		::clock_gettime(CLOCK_MONOTONIC, &ts);
		return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
	}
};

} /* namespace cacheserver */


#endif /* LISTENHANDLER_H_ */
